import Vue from 'vue'
import router from '../router'
import axios from 'axios'
import store from '@/store'
import { VueAxios } from './axios'
import { notification, message } from 'ant-design-vue'
import { ACCESS_TOKEN, USER_NAME, SM2_PUBLIC_KEY, SM4_KEY } from "@/store/mutation-types"
import { sm2Encrypt } from '@/utils/sm2'
import { sm3Hash } from '@/utils/sm3'
import { sortAsc, isJSON, parseQueryString } from '@/utils/util'
import qs from 'qs'

/**
 * 【指定 axios的 baseURL】
 * 如果手工指定 baseURL: '/jeecg-boot'
 * 则映射后端域名，通过 vue.config.js
 * @type {*|string}
 */
let apiBaseUrl = process.env.VUE_APP_DOMAIN_URL || "/mesh-controller";
//console.log("apiBaseUrl= ",apiBaseUrl)
// 创建 axios 实例
const service = axios.create({
  //baseURL: '/jeecg-boot',
  baseURL: apiBaseUrl, // api base_url
  timeout: 30000 // 请求超时时间
})

const err = (error) => {
  if (error.response) {
    let that = this;
    let data = error.response.data
    const token = Vue.ls.get(ACCESS_TOKEN)
    // console.log("------异常响应------",token)
    // console.log("------异常响应------",error.response.status)
    switch (error.response.status) {
    case 403:
      notification.error({ message: '系统提示', description: '拒绝访问', duration: 4 })
      break
    case 500:
      //notification.error({ message: '系统提示', description:'Token失效，请重新登录!',duration: 4})
      if (data.message === "Token失效，请重新登录") {
        if (process.env.VUE_APP_MODE === "sso") {
          store.dispatch('Logout').then(() => {
            router.push({
              path: '/skip',
              query: {
                type: 'logout',
                username:  Vue.ls.get(USER_NAME)
              } 
            });
          });
        } else {
          store.dispatch('Logout').then(() => {
            router.push({ path: '/user/login' })
          })
        }
      }
        // update-end- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式，不直接跳转----
      break
    case 404:
      notification.error({ message: '系统提示', description: '很抱歉，资源未找到!', duration: 4 })
      break
    case 504:
      notification.error({ message: '系统提示', description: '网络超时' })
      break
    case 401:
      // notification.error({ message: '系统提示', description:'未授权，请重新登录',duration: 4})
      if (process.env.VUE_APP_MODE === "sso") {
        store.dispatch('Logout').then(() => {
          router.push({
            path: '/skip',
            query: {
              type: 'logout',
              username:  Vue.ls.get(USER_NAME)
            } 
          });
        })  
      } else if (token) {
        store.dispatch('Logout').then(() => {
          router.push({ path: '/user/login' });
        })
      }
      break
    default:
      notification.error({
        message: '系统提示',
        description: data.message,
        duration: 4
      })
      break
    }
  }
  return Promise.reject(error)
};

// request interceptor
service.interceptors.request.use(config => {
  const token = Vue.ls.get(ACCESS_TOKEN)
  if (token) {
    config.headers['X-Access-Token'] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
  }
  if (Vue.ls.get(SM2_PUBLIC_KEY) &&
    (config.url.indexOf("createSwitcher") > 0 ||
    config.url.indexOf("createNode") > 0 ||
    config.url.indexOf("detailNode") > 0 ||
    config.url.indexOf("detailSwitcher") > 0 ||
    config.url.indexOf("pageSwitcher") > 0 ||
    config.url.indexOf("updateNode") > 0 ||
    config.url.indexOf("updateSwitcher") > 0)) {
    const sm4Key = sm2Encrypt(Vue.ls.get(SM4_KEY), Vue.ls.get(SM2_PUBLIC_KEY));
    config.headers['sm-token'] = sm4Key
  }
  //update-begin-author:taoyan date:2020707 for:多租户
  // let tenantid = Vue.ls.get(TENANT_ID)
  // if (!tenantid) {
  //   tenantid = 0;
  // }
  // config.headers['tenant_id'] = tenantid
  //update-end-author:taoyan date:2020707 for:多租户
  if (config.method == 'get') {
    if (config.url.indexOf("sys/dict/getDictItems") < 0) {
      config.params = {
        _t: Date.parse(new Date()) / 1000,
        ...config.params
      }
    }
  }
  if (!config.baseURL) {
    config.baseURL = '/mesh-controller'
  }

  // 参数防篡改处理
  let requestData = {};
  if (config.method === 'get' && config.params) {
    requestData = parseQueryString(decodeURIComponent(qs.stringify(config.params, { arrayFormat: 'indices' })));
  } else if (config.data) {
    if (isJSON(config.data)) {
      requestData = JSON.parse(config.data);
    } else {
      requestData = parseQueryString(decodeURIComponent(config.data));
    }
  }

  if (requestData) {
    let etag = ''
    if (requestData.title) {
      etag += requestData.title;
    }
    etag += '>';
    if (requestData.content) {
      etag += requestData.content;
    }
    if (etag.length > 1) {
      config.headers['ETag'] = encodeURIComponent(etag);
    }
  }

  let sign = '';
  let timeStamp = (new Date()).getTime();
  sign += JSON.stringify(sortAsc(requestData));
  sign += timeStamp;
  sign += '_fc95e4f0ff6648d3aa1fac90db6b7bf4'; // 最后加个尾巴
  if (config.url.indexOf("sys/login") < 0) {
    config.headers['Sign'] = sm3Hash(sign);
    config.headers['Timestamp'] = timeStamp;
  }

  // if (config.baseURL === '/gce') {
  //   config.headers[ 'X-USER-ID' ] = 'cc81efe719bf4b05a3c21524ccf6c1ea'
  //   config.headers[ 'x-gce-tenant-id' ] = 'f6d4b7a3-db29-476b-aaa2-392fad843442'
  //   config.headers[ 'X-TOKENID-IDS' ] = 'f6d4b7a3-db29-476b-aaa2-392fad843442'
  //   config.headers[ 'Content-Type' ] = 'application/x-www-form-urlencoded'
  // }

  // if (config.url.indexOf("app/sync") > -1) {
  //   config.headers[ 'Content-Type' ] = 'application/json;charset=UTF-8'
  // }
  return config
}, (error) => {
  return Promise.reject(error)
})

// response interceptor
service.interceptors.response.use((response) => {
  if (response.headers.sm2) {
    Vue.ls.set(SM2_PUBLIC_KEY, response.headers.sm2)
  }
  // if (response.headers.sm3) {
  //   Vue.ls.set(SM3_HASH_CODE, response.headers.sm3)
  // }
  const res = response.data
  if (res === "签名不允许为空。" || res === "时间戳不允许为空。" || res === "签名已过期。" || res === "完整性被破坏，请注意数据安全。") {
    message.warning(res)
  } else if (!res.success) {
    message.warning(res.errorCode || res.message || "操作失败")
  }
  return res
}, err)

const installer = {
  vm: {},
  install(Vue, router = {}) {
    Vue.use(VueAxios, router, service)
  }
}

export {
  installer as VueAxios,
  service as axios
}